home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dskut
/
fhard101.zip
/
VHPREP.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-07-17
|
20KB
|
745 lines
title Prepare VHARD floppies
subttl Prologue
page 60,132
comment {
******************************************************************************
File VHPREP.ASM
Author:
Aaron L. Brenner
BIX mail address albrenner
GEnie address A.BRENNER
This program is hereby released to the public domain.
Purpose:
Prepare floppy diskettes for use with VHARD.
This consists of the following:
1) Format the floppies to 10 sectors per track, 40 tracks (resulting
in a capacity of 800K per diskette).
2) Write the VHARD boot sector to each disk containing, along with
boot code, a disk ID and number.
3) Write a DOS boot sector, 2 FATs, and root directory to the first
disk.
All disk operations are performed through VHARDCTL, the character
device driver installed with VHARD.
Errorlevel returned:
0 All is well
1 VHARD.SYS is not installed
Revision history:
1.00 07/11/90 ALB Created.
******************************************************************************
endcomment {
subttl Included files
page
include dd_defs.inc
include vhard.inc
subttl Program data and stack
page
vhprep_data segment para
ID_to_use db 8 dup(' ') ; ID to use for the diskettes
disk_num db 0ffh ; Number for each diskette
track_buf db 512 * 10 dup(0) ; Track buffer for reading and writing
drive_num db 0 ; The drive assigned to VHARD
vhard_vnum dw 0 ; Version of VHARD
VHARD_BPB DOS_BPB <> ; BPB gotten from VHARD
dw 81h ; Pointer to our command tail
our_PSP dw 0 ; Our PSP segment
;
; This block is used to pass commands to VHPREP
;
command_blk VH_CMD <>
vhctl_name db 'VHARDCTL',0 ; Name of control driver for VHARD
vhctl_handle dw 0 ; Handle for VHARDCTL
not_installed db 13,10,'The VHARD driver is not installed.',13,10,'$'
insert_disk db 13,10,'Put a blank diskette in drive A:, then press'
db ' a key $'
label_disk db 'Label this diskette $'
disk_bad db 7,13,10,'This diskette is unusable!',13,10,'$'
crlf_str db 13,10,'$'
err_prefix db 7,'Error: $'
err0 db 'spurious error message$'
err1 db 'drive/adapter failed or no disk in drive$'
err2 db 'seek operation failed$'
err3 db 'disk adapter failed$'
err4 db 'CRC error$'
err5 db 'attempt to DMA across segment boundary$'
err6 db 'DMA overrun$'
err7 db 'sector not found$'
err8 db 'diskette is write-protected$'
err9 db 'address mark not found$'
err10 db 'invalid BIOS command$'
err11 db 'internal command error$'
err0ff db 'unknown BIOS error code$'
error_msgs dw err0, err1, err2, err3, err4, err5, err6, err7, err8
dw err9, err10, err11, err0, err0, err0ff
vhprep_data ends
vhprep_stack segment word stack
dw 256 dup(0)
vhprep_stack ends
;*****************************************************************************
;
; This gets written to the actual boot sector of each diskette. As you can
; see, it just spits out a message, waits for a key, then tries to IPL again.
;
;*****************************************************************************
boot_code_seg segment para
assume cs:boot_code_seg, ds:boot_code_seg
org 0
boot_code proc near
jmp short boot_msg_disp ; Jump to message display code
db 17 dup(?) ; Place keeper for disk ID & number
boot_msg_disp:
cld ; Make sure of direction
call do_display ; Do the display
db 7,'This is NOT a bootable diskette!',13,10
db 'Put a different disk in the drive, and press a key to'
db ' try again',13,10,0
do_display:
pop si ; Point to the string to display
ddsp_l1:
lods byte ptr cs:[si] ; Get a byte
or al,al ; End of string yet?
jz ddsp_l2 ; Yep - just hang up now
mov ah,14 ; BIOS "Write TTY" function
int 10h ;
jmp short ddsp_l1 ; Loop back for the rest
ddsp_l2:
sub ah,ah ; Get a key
int 16h ;
int 19h ; Try to IPL again
jmp $ ; Hang up now
boot_code_end label byte
boot_code endp
boot_code_seg ends
subttl Start of program code
page
vhprep_code segment
assume cs:vhprep_code, ds:vhprep_data, es:vhprep_data, ss:vhprep_stack
start proc
call initialize ; Set things up
call do_prep ; Do the preparation
call terminate ; Do program cleanup
mov ax,4c00h ;
int 21h ;
start endp
;*****************************************************************************
;
; Program initialization.
;
; Make sure the VHARDCTL driver is present, and get driver info from it.
;
;*****************************************************************************
initialize proc near
mov ax,vhprep_data ; Get our data segment
mov ds,ax ;
mov our_PSP,es ; Save our PSP segment
mov es,ax ;
mov dx,offset vhctl_name ; Try to open VHARDCTL, read/write
mov ax,3d02h ;
int 21h ;
jnc init_l1 ; If it opened, make sure it's a dev
init_noway:
mov dx,offset not_installed ; Complain that it isn't there
mov ah,9 ;
int 21h ;
mov ax,4c01h ; Exit with errorlevel of 1
int 21h ;
init_l1:
mov vhctl_handle,ax ; Save the handle for other ops
mov bx,ax ; Get the handle for IOCTL call
mov ax,4400h ; Get info on this guy
int 21h ;
test dl,80h ; Is this a device?
jz init_noway ; Nope - no way we're doing anything
mov command_blk.VC_cmd_code,CMD_GETDATA
mov word ptr command_blk.VC_buffer[0],offset drive_num
mov word ptr command_blk.VC_buffer[2],ds
mov ax,4403h ; Get data from VHARDCTL
mov dx,offset command_blk ;
mov cx,size VH_CMD ;
int 21h ;
call get_cmdline_parms ; Get a parameters from the cmd line
cmp byte ptr ID_to_use[0],' '; Did they supply an ID?
jne init_exit ; Yep - don't change it
mov ah,0 ; Get timer count from BIOS
int 1ah ; Returns CX:DX
mov ax,'HV' ; Set up disk ID
mov word ptr ID_to_use[0],ax;
mov ax,cx ; Use the time as part of the ID
mov di,offset ID_to_use[2] ;
call store2digits ;
mov al,dh ;
call store2digits ;
mov al,dl ;
call store2digits ;
init_exit:
ret ; Return to Main
initialize endp
;*****************************************************************************
;
; Get any command line parameters
;
; The only parameters allowed are a disk ID and a disk number.
;
;*****************************************************************************
get_cmdline_parms proc near
push es ; Save it for this
les si,dword ptr our_PSP[-2]; Point to the command tail
call skip_spaces ; Skip any whitespace
mov cx,8 ; Max to copy
mov di,offset ID_to_use ;
gcmp_l1:
lods byte ptr es:[si] ; Get a byte
cmp al,' ' ; Whitespace?
je gcmp_l3 ; Yep - stop copying
cmp al,9 ;
je gcmp_l3 ;
cmp al,0dh ; End of it?
je gcmp_exit ; Yep - exit
cmp al,'a' ; Lower case?
jb gcmp_l2 ; No - never mind
cmp al,'z' ;
ja gcmp_l2 ;
xor al,20h ; Make it upper case
gcmp_l2:
jcxz gcmp_l1 ; Don't store if ID is full
mov [di],al ; Save the byte
inc di ; Point to next spot
dec cx ; Knock off the count
jmp gcmp_l1 ; Loop back
gcmp_l3:
call skip_spaces ; Skip any other whitespace
sub bl,bl ; Clear accumulator
gcmp_l4:
lods byte ptr es:[si] ; Pick up a byte
cmp al,'0' ; Valid digit?
jb gcmp_l5 ; Nope - stop now
cmp al,'9' ;
ja gcmp_l5 ;
sub al,'0' ; Make digit binary
mov bh,bl ; Multiply current value by 10
shl bh,1 ; by (BL * 2) + (BL * 8)
shl bl,1 ;
shl bl,1 ;
shl bl,1 ;
add bl,al ; Add in new digit
jmp short gcmp_l4 ; Loop back
gcmp_l5:
cmp bl,12 ; Make sure it's legal
ja gcmp_exit ;
mov disk_num,bl ; Save the number
gcmp_exit:
pop es ;
ret ; Return to initialization
get_cmdline_parms endp
;*****************************************************************************
;
; Skip whitespace characters at ES:SI
;
;*****************************************************************************
skip_spaces proc near
sksp_l1:
mov al,es:[si] ; Get a byte
cmp al,' ' ; Whitespace?
je sksp_l2 ; Yep - skip it
cmp al,9 ;
jne sksp_exit ; No - exit now
sksp_l2:
inc si ; Skip this character
jmp short sksp_l1 ; Loop back
sksp_exit:
ret ; Re